#include "lab2_problem4.h"

#include <stdint.h>
#include <iostream>

#include "../p3/newton.h"

namespace Lab2
{
    namespace Problem4
    {
        namespace
        {
            // Number to estimate the root of. 
            double gNumber = 0.0;

            // Estimation function for Newton algorithm.
            double CubicRoot(const double x) 
            { 
            	return x * x * x - gNumber; 
            }

            // Derived of the estimation function.
            double Derived(const double x) 
            { 
            	return 3.0 * x * x; 
            }
        }        
                 
        void problem4()
        {
        	// Max number of iterations
        	const uint32_t maxIterations = 10000;

            std::cout << "Lab 2 - Problem 4:" << std::endl;

        	// Ask the user for a positive number to calculate the cubic root.
        	// The number must be positive.
        	while(gNumber <= 0.0)
        	{
        		std::cout << "Enter a positive number to estimate its cubic root:" << std::endl;
        		std::cin >> gNumber;
        	}

        	// Ask the user for the initial estimation.
        	std::cout << "Enter the initial estimation of Newton algorithm:" << std::endl;
        	double initialEstimation = 0.0;
        	std::cin >> initialEstimation;
        	
        	// Ask the user for the stopping bound.
        	std::cout << "Enter the stopping bound for the Newton algorithm:" << std::endl;
        	double stopBound = 0.0;
        	std::cin >> stopBound;

        	// Build the newton input data.
        	const NumericalAnalysis::NewtonInputData inputData(CubicRoot, Derived, initialEstimation, maxIterations, stopBound);

        	// Calculate the newton output data.
        	const NumericalAnalysis::NewtonOutputData outputData = NumericalAnalysis::NewtonMethod(inputData);

        	// Print information.
        	std::cout << "Final estimation = " << outputData.mFinalEstimation << std::endl;
        	std::cout << "Number of iterations = " << outputData.mFinalIterationNumber << std::endl;
        }    
    }
}
